package com.bruce.asurada.sso.client.service;

import com.bruce.asurada.sso.client.common.Result;
import com.bruce.asurada.sso.client.config.SsoProperties;
import com.bruce.asurada.sso.client.dto.LoginResponseDto;
import com.bruce.asurada.sso.client.dto.UserInfoDto;
import com.bruce.asurada.sso.client.dto.UserLoginDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

/**
 * SSO客户端服务
 * 负责与SSO服务端进行通信
 * 
 * @author Bruce
 */
@Slf4j
@Service
public class SsoClientService {

    @Autowired
    private SsoProperties ssoProperties;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 用户登录
     */
    public Result<LoginResponseDto> login(UserLoginDto loginDto, String redirect) {
        try {
            String loginUrl = ssoProperties.getServer().getLoginUrl();
            
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("username", loginDto.getAccount());
            params.add("password", loginDto.getPassword());
            params.add("clientId", ssoProperties.getClient().getId());
            if (redirect != null) {
                params.add("redirect", redirect);
            }
            
            // 发送登录请求
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params);
            ResponseEntity<Result<LoginResponseDto>> response = restTemplate.exchange(
                loginUrl,
                HttpMethod.POST,
                request,
                new ParameterizedTypeReference<Result<LoginResponseDto>>() {}
            );
            
            Result<LoginResponseDto> result = response.getBody();
            if (result != null && result.isSuccess()) {
                log.info("用户登录成功: {}", loginDto.getAccount());
            }
            
            return result;
        } catch (Exception e) {
            log.error("登录请求失败: {}", e.getMessage(), e);
            return Result.error("登录失败: " + e.getMessage());
        }
    }

    /**
     * 验证令牌
     */
    public Result<UserInfoDto> verifyToken(String token) {
        try {
            String verifyUrl = ssoProperties.getServer().getVerifyUrl();
            
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            
            HttpEntity<Void> request = new HttpEntity<>(headers);
            ResponseEntity<Result<UserInfoDto>> response = restTemplate.exchange(
                verifyUrl,
                HttpMethod.GET,
                request,
                new ParameterizedTypeReference<Result<UserInfoDto>>() {}
            );
            
            return response.getBody();
        } catch (Exception e) {
            log.error("令牌验证失败: {}", e.getMessage(), e);
            return Result.unauthorized("令牌验证失败");
        }
    }

    /**
     * 检查登录状态
     */
    public Result<Boolean> checkLoginStatus(String token) {
        try {
            String checkUrl = ssoProperties.getServer().getCheckUrl();
            
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            
            HttpEntity<Void> request = new HttpEntity<>(headers);
            ResponseEntity<Result<Boolean>> response = restTemplate.exchange(
                checkUrl,
                HttpMethod.GET,
                request,
                new ParameterizedTypeReference<Result<Boolean>>() {}
            );
            
            return response.getBody();
        } catch (Exception e) {
            log.error("检查登录状态失败: {}", e.getMessage(), e);
            return Result.success("登录状态检查完成", false);
        }
    }

    /**
     * 用户登出
     */
    public Result<Void> logout(String token, String redirect) {
        try {
            String logoutUrl = ssoProperties.getServer().getLogoutUrl();
            
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("token", token);
            params.add("clientId", ssoProperties.getClient().getId());
            if (redirect != null) {
                params.add("redirect", redirect);
            }
            
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params);
            ResponseEntity<Result<Void>> response = restTemplate.exchange(
                logoutUrl,
                HttpMethod.POST,
                request,
                new ParameterizedTypeReference<Result<Void>>() {}
            );
            
            log.info("用户登出成功");
            return response.getBody();
        } catch (Exception e) {
            log.error("登出请求失败: {}", e.getMessage(), e);
            return Result.error("登出失败: " + e.getMessage());
        }
    }

    /**
     * 刷新令牌
     */
    public Result<LoginResponseDto> refreshToken(String refreshToken) {
        try {
            String refreshUrl = ssoProperties.getServer().getRefreshUrl();
            
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("refreshToken", refreshToken);
            params.add("clientId", ssoProperties.getClient().getId());
            
            HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params);
            ResponseEntity<Result<LoginResponseDto>> response = restTemplate.exchange(
                refreshUrl,
                HttpMethod.POST,
                request,
                new ParameterizedTypeReference<Result<LoginResponseDto>>() {}
            );
            
            Result<LoginResponseDto> result = response.getBody();
            if (result != null && result.isSuccess()) {
                log.info("令牌刷新成功");
            }
            
            return result;
        } catch (Exception e) {
            log.error("令牌刷新失败: {}", e.getMessage(), e);
            return Result.error("令牌刷新失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户信息
     */
    public Result<UserInfoDto> getUserInfo(String token) {
        try {
            String userinfoUrl = ssoProperties.getServer().getUserinfoUrl();
            
            // 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(token);
            
            HttpEntity<Void> request = new HttpEntity<>(headers);
            ResponseEntity<Result<UserInfoDto>> response = restTemplate.exchange(
                userinfoUrl,
                HttpMethod.GET,
                request,
                new ParameterizedTypeReference<Result<UserInfoDto>>() {}
            );
            
            return response.getBody();
        } catch (Exception e) {
            log.error("获取用户信息失败: {}", e.getMessage(), e);
            return Result.error("获取用户信息失败: " + e.getMessage());
        }
    }
}